package com.zhenwei.zscm.service;

import cn.hutool.core.util.StrUtil;
import com.zhenwei.zscm.common.base.RestMsg;
import com.zhenwei.zscm.common.base.RestResult;
import com.zhenwei.zscm.common.base.UserContext;
import com.zhenwei.zscm.common.exception.CustomException;
import com.zhenwei.zscm.common.utils.Linq;
import com.zhenwei.zscm.mappings.OrderProductCheckPriceMapping;
import com.zhenwei.zscm.model.dto.file.FileRelationDTO;
import com.zhenwei.zscm.model.dto.order.OrderProductCheckDTO;
import com.zhenwei.zscm.model.dto.order.OrderProductCheckDetailDTO;
import com.zhenwei.zscm.model.dto.order.OrderProductCheckPriceDTO;
import com.zhenwei.zscm.model.dto.order.OrderProductDTO;
import com.zhenwei.zscm.model.dto.productPart.ProductPartDTO;
import com.zhenwei.zscm.model.enums.OrderStatusEnum;
import com.zhenwei.zscm.model.enums.RepairStateEnum;
import com.zhenwei.zscm.model.vo.orderProductCheck.OneKeyPriceVO;
import com.zhenwei.zscm.model.vo.orderProductCheck.OrderProductCheckVO;
import com.zhenwei.zscm.repo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

@Service
@AllArgsConstructor
public class OrderProductCheckService {
    private OrderProductCheckPriceRepo orderProductCheckPriceRepo;
    private OrderRepo orderRepo;
    private OrderProductRepo orderProductRepo;
    private OrderProductCheckRepo orderProductCheckRepo;
    private ProductPartRepo productPartRepo;
    private FileRelationRepo fileRelationRepo;
    private LogRepo logRepo;
    private final String LOG_TYPE = "售后工单检测";

    @Transactional(rollbackFor = {CustomException.class, Exception.class})
    public RestResult create(OrderProductCheckVO vo){
        // 检查工单是否存在
        String checkResult = orderRepo.checkOrderStatus(vo.getOrderId());
        if (!"".equals(checkResult)){
            return RestResult.fail(checkResult);
        }
        // 检查要保存的产品是否存在
        OrderProductDTO orderProduct = orderProductRepo.get(vo.getOrderId(), vo.getProductSn());
        if(orderProduct == null){
            return RestResult.fail(RestMsg.ORDER_PRODUCT_NOT_EXISTS);
        }
        // 检查权限及状态
        if(UserContext.isNotAdmin() && orderProduct.getRepairStateCode().equals(RepairStateEnum.REPAIRED.name())) {
            return RestResult.fail(RestMsg.ORDER_PRODUCT_REPAIRED);
        }
        // 检查工单是否已经添加过检测数据
        var orderProductCheck = orderProductCheckRepo.getDetail(vo.getOrderId(), vo.getProductSn());
        if(orderProductCheck != null){
            return RestResult.fail(RestMsg.ORDER_PRODUCT_CHECK_EXISTS);
        }
        // 保存产品检测表数据
        boolean success = orderProductCheckRepo.create(vo);
        if(!success){
            return RestResult.fail(RestMsg.FAILURE);
        }
        // 保存检测价格数据
        if(Linq.isNotEmpty(vo.getPrices())) {
            List<OrderProductCheckPriceDTO> priceList = Linq.mapList(vo.getPrices(), OrderProductCheckPriceMapping.INSTANCE::vo2DTO);
            List<ProductPartDTO> productPartList = productPartRepo.getProductPartByProductCode(orderProduct.getProductCode());
            // 计算配件价格
            priceList.forEach(price -> {
                price.setOrderId(vo.getOrderId());
                price.setProductSn(orderProduct.getProductSn());
                ProductPartDTO part = Linq.findFirst(productPartList, x -> x.getGuid().equals(price.getProductPartId()));
                if(part != null){
                    price.setProductPartName(part.getPartName());
                    price.setPrice(part.getPrice());
                    var totalPrice = part.getPrice().multiply(BigDecimal.valueOf(price.getCount())).setScale(2, RoundingMode.HALF_UP);
                    price.setTotalPrice(totalPrice);
                }
            });
            success = orderProductCheckPriceRepo.createCheckPrice(priceList);
            if(!success){
                throw new CustomException(RestMsg.FAILURE);
            }
        }
        // 更新一下订单的状态
        boolean updated = orderRepo.updateStatus(vo.getOrderId(), OrderStatusEnum.PROCESSING);
        if(!updated) {
            throw new CustomException(RestMsg.FAILURE);
        }
        // 保存一下上传的文件
        if(Linq.isNotEmpty(vo.getFileIdList())) {
            boolean saved = fileRelationRepo.saveRelation(vo.getOrderId()+vo.getProductSn(),vo.getFileIdList());
            if(!saved) {
                throw new CustomException(RestMsg.FAILURE);
            }
        }
        // 根据报价数据判断一下产品处理状态
        String quoteState = vo.getQuoteState();
        RepairStateEnum repairStateEnum = RepairStateEnum.SALE_PRICE;
        if(StrUtil.isNotBlank(quoteState) && "是".equals(quoteState)){
            repairStateEnum = RepairStateEnum.CONFIRMING;
        }
        if(vo.getIsQuoteConfirm()) {
            repairStateEnum = RepairStateEnum.REPAIRING;
        }
        orderProductRepo.updateState(vo.getOrderId(), vo.getProductSn(), repairStateEnum.name());
        logRepo.createAsync(LOG_TYPE, "添加检测数据->"+vo);
        return RestResult.success();
    }

    @Transactional(rollbackFor = {CustomException.class, Exception.class})
    public RestResult update(OrderProductCheckVO vo) {
        // 检查工单是否存在
        String checkResult = orderRepo.checkOrderStatus(vo.getOrderId());
        if (!"".equals(checkResult)){
            return RestResult.fail(checkResult);
        }
        // 检查要保存的产品是否存在
        OrderProductDTO orderProduct = orderProductRepo.get(vo.getOrderId(), vo.getProductSn());
        if(orderProduct == null){
            return RestResult.fail(RestMsg.ORDER_PRODUCT_NOT_EXISTS);
        }
        // 检查权限及状态
        if(UserContext.isNotAdmin() && orderProduct.getRepairStateCode().equals(RepairStateEnum.REPAIRED.name())) {
            return RestResult.fail(RestMsg.ORDER_PRODUCT_REPAIRED);
        }
        // 检查工单是否已经添加过检测数据
        var orderProductCheck = orderProductCheckRepo.getDetail(vo.getOrderId(), vo.getProductSn());
        if(orderProductCheck == null){
            return RestResult.fail(RestMsg.ORDER_PRODUCT_CHECK_NOT_EXISTS);
        }
        // 更新主表数据
        boolean updated = orderProductCheckRepo.update(vo);
        if(!updated){
            return RestResult.fail(RestMsg.FAILURE);
        }
        // 更新配件表数据，先删后插
        orderProductCheckPriceRepo.delete(vo.getOrderId(), orderProduct.getProductSn());
        if(Linq.isNotEmpty(vo.getPrices())) {
            List<OrderProductCheckPriceDTO> priceList = Linq.mapList(vo.getPrices(), OrderProductCheckPriceMapping.INSTANCE::vo2DTO);
            List<ProductPartDTO> productPartList = productPartRepo.getProductPartByProductCode(orderProduct.getProductCode());
            // 计算配件价格
            priceList.forEach(price -> {
                price.setOrderId(vo.getOrderId());
                price.setProductSn(orderProduct.getProductSn());
                ProductPartDTO part = Linq.findFirst(productPartList, x -> x.getGuid().equals(price.getProductPartId()));
                if(part != null){
                    price.setProductPartName(part.getPartName());
                    price.setPrice(part.getPrice());
                    var totalPrice = part.getPrice().multiply(BigDecimal.valueOf(price.getCount())).setScale(2, RoundingMode.HALF_UP);
                    price.setTotalPrice(totalPrice);
                }
            });
            var success = orderProductCheckPriceRepo.createCheckPrice(priceList);
            if(!success){
                throw new CustomException(RestMsg.FAILURE);
            }
        }
        //
        fileRelationRepo.delete(vo.getOrderId()+vo.getProductSn());
        if(Linq.isNotEmpty(vo.getFileIdList())){
            boolean saved = fileRelationRepo.saveRelation(vo.getOrderId()+vo.getProductSn(),vo.getFileIdList());
            if(!saved) {
                throw new CustomException(RestMsg.FAILURE);
            }
        }
        // 根据报价数据判断一下产品处理状态
        String quoteState = vo.getQuoteState();
        RepairStateEnum repairStateEnum = RepairStateEnum.SALE_PRICE;
        if(StrUtil.isNotBlank(quoteState) && "是".equals(quoteState)){
            repairStateEnum = RepairStateEnum.CONFIRMING;
        }
        if(vo.getIsQuoteConfirm()) {
            repairStateEnum = RepairStateEnum.REPAIRING;
        }
        orderProductRepo.updateState(vo.getOrderId(), vo.getProductSn(), repairStateEnum.name());
        logRepo.createAsync(LOG_TYPE, "修改检测数据->"+vo);
        return RestResult.success();
    }

    public RestResult detail(String orderId, String productSn) {
        OrderProductCheckDetailDTO detail = new OrderProductCheckDetailDTO();
        OrderProductCheckDTO orderProductCheck = orderProductCheckRepo.getDetail(orderId, productSn);
        detail.setCheck(orderProductCheck);
        // 获取报价
        List<OrderProductCheckPriceDTO> priceList = orderProductCheckPriceRepo.list(orderId, productSn);
        detail.setPrices(priceList);

        List<FileRelationDTO> files = fileRelationRepo.getFiles(orderId + productSn);
        detail.setFileIds(Linq.mapList(files, FileRelationDTO::getFileId));
        return RestResult.success(detail, 0);
    }

    @Transactional(rollbackFor = {CustomException.class, Exception.class})
    public RestResult oneKeyPrice(OneKeyPriceVO vo) {
        boolean updated = orderProductCheckRepo.oneKeyPrice(vo);
        if (updated){
            // 更新产品状态
            List<OrderProductCheckDTO> checkList = orderProductCheckRepo.getList(vo.getOrderId());
            List<String> selected = Linq.select(checkList, OrderProductCheckDTO::getProductSn);
            updated = orderProductRepo.updateState(vo.getOrderId(), selected, RepairStateEnum.CONFIRMING.name());
            if(!updated){
                throw new CustomException(RestMsg.FAILURE);
            }
        }
        return RestResult.r(updated);
    }
}
